/*
 * Copyright (c) 2023-2299 深圳市阿毛科技有限公司 All rights reserved.
 *
 * https://www.lamyz.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */
package com.lam.common.utils.passwd;

import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;

import com.lam.common.components.redis.RedisUtil;
import com.lam.common.context.AuthTypeEnum;
import com.lam.common.exception.BusinessException;
import com.lam.common.utils.IpUtils;
import com.lam.common.utils.NumberUtil;
import com.lam.common.utils.SpringUtils;
import com.lam.common.utils.StringUtils;

import cn.hutool.core.util.StrUtil;

/**
 */
public class PasswordCheckManager {

    private static PasswordEncoder passwordEncoder;
    
    public static PasswordEncoder getPasswordEncoder() {
    	if(passwordEncoder == null) {
    		passwordEncoder = SpringUtils.getBean(PasswordEncoder.class);
    	}
    	if(passwordEncoder == null) {
    		passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
    	}
    	return passwordEncoder;
    }

    /**
     * 半小时内最多错误10次
     */
    private static final int TIMES_CHECK_INPUT_PASSWORD_NUM = 10;
    
    public static void checkPassword(AuthTypeEnum authTypeEnum,String userNameOrMobile, String rawPassword, String encodedPassword) {

    	//检查用户输入错误的验证码次数
        String checkPrefix = String.format("%s_UserInputErrorPassword_%s", authTypeEnum.getAuthType(), IpUtils.getIpAddr());
        String key = checkPrefix + userNameOrMobile;
        int count = 0;
        if(RedisUtil.hasKey(key)){
            count = NumberUtil.toInt(RedisUtil.get(key), TIMES_CHECK_INPUT_PASSWORD_NUM);
        }
        if(count >= TIMES_CHECK_INPUT_PASSWORD_NUM){
            throw new BusinessException("密码输入错误十次，已限制登录30分钟");
        }
        // 半小时后失效
        RedisUtil.set(key, count, 1800);
        // 密码不正确
//        if (StrUtil.isBlank(encodedPassword) || !getPasswordEncoder().matches(rawPassword, encodedPassword)){
        if (StrUtil.isBlank(encodedPassword) || !StringUtils.equals(rawPassword, encodedPassword)){
            count++;
            // 半小时后失效
            RedisUtil.set(key ,count,1800);
            throw new BusinessException("账号或密码不正确");
        }
    }
}
